<template>
  <div class="department-container">
    <div class="app-container">
      <!-- 卡片布局 纯布局组件 -->
      <el-card>
        <!-- 用一个行列布局 栅格布局？分成24然后根据分数划分结构-->
        <!-- 行列布局 形成了一个5:1关系 -->
        <el-row type="flex" justify="space-between" align="middle" style="height: 40px">
          <el-col :span="20">
            <span>江苏传智播客教育科技股份有限公司</span>
          </el-col>
          <el-col :span="4">
            <el-row type="flex" justify="end">
              <!-- 两个内容 -->
              <el-col>负责人</el-col>
              <el-col>操作</el-col>
            </el-row>
          </el-col>
        </el-row>
        <!-- tree型布局 -->
        <!-- 结构的特殊性 要求传入的list也必须是一个树形数据 -->
        <!--
          属性是否加冒号
          1. 加冒号  后面会识别为表达式  data中的响应式数据 或者 true 123 [1,2,3]
          2. 不加冒号  识别为字符串 string
         -->
        <el-tree :data="list" :props="defaultProps" :default-expand-all="true">
          <!-- 默认插槽 作用域插槽写法 -->
          <!--
            data是一个对象 代表当前行的节点对象数据
            里面有我们name属性
            { data }  解构赋值中的data一定是固定的 解构赋值要求匹配对象属性 组件内部抛出的就是属性名称为data的对象
            #default="scoped"  不解构赋值 名字不是固定的 类似于一个函数的形参 但是要保持语义化
           -->
          <template #default="{ data }">
            <el-row
              type="flex"
              justify="space-between"
              align="middle"
              style="height: 40px; width: 100%;"
            >
              <el-col :span="20">
                <!-- 从对象中拿到我们的name属性渲染 -->
                <span>{{ data.name }}</span>
              </el-col>
              <el-col :span="4">
                <el-row type="flex" justify="end">
                  <!-- 两个内容 -->
                  <el-col>{{ data.manager }}</el-col>
                  <el-col>
                    <!-- 下拉菜单 element -->
                    <el-dropdown>
                      <!-- 操作栏 一样可以通过data.id 回调函数传入 -->
                      <span> 操作<i class="el-icon-arrow-down" /> </span>
                      <el-dropdown-menu slot="dropdown">
                        <!-- 这里为啥native？
                           在vue中给一个组件写一个@click默认会识别为自定义事件 加上.native之后vue会帮助我们给组件中
                           的根元素绑定一个原生的click 这时候点击就会生效

                           el-button  @click 不需要加native? 是因为button本身从语义上就是按钮 按钮就是用来点击的
                           所以在组件内部它已经绑定好了时间并且通过this.$emit('click')
                         -->
                        <el-dropdown-item @click.native="addDepart(data.id)">添加子部门</el-dropdown-item>
                        <el-dropdown-item>编辑部门</el-dropdown-item>
                        <el-dropdown-item>删除部门</el-dropdown-item>
                      </el-dropdown-menu>
                    </el-dropdown>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-tree>
      </el-card>
    </div>
    <!-- 弹框 -->
    <el-dialog
      title="提示"
      :visible="dialogVisible"
      width="30%"
      @close="closeDialog"
      @open="openDialog"
    >
      <!-- 从外到里 表单校验：字段名称一定要对应 -->
      <el-form ref="addForm" label-width="120px" :model="form" :rules="rules">
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="form.name" style="width:80%" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input v-model="form.code" style="width:80%" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select v-model="form.manager" style="width:80%" placeholder="请选择">
            <!--
              key: 和v-for配合
              label: 下拉时显示的中文文案
              value：选中某一项时自动绑定到select v-model的数据 通常这个value需要和后端交互
              作为接口数据提交给后端 具体要绑定哪个字段由后端来决定
             -->
            <el-option
              v-for="item in managerList"
              :key="item.id"
              :label="item.username"
              :value="item.username"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="form.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" />
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="confirm">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
// 查
// 1. 根据接口文档准备api接口函数 封装一下
// 2. 在组件中正确的导入这个api函数
// 3. 在data中准备一个响应式的用来承接后台数据的属性
// 4. methods中准备一个函数 在其中调用接口
// 5. 选择一个合适的生命周期钩子函数 调用4中的方法

// created vs mounted ? 没区别 错误的观念 created要比mounted好 要快 这个思想是不对的
// 生命周期的时间差和接口的从发起到返回的这个时间差 可以忽略不计 并不能作为一个优化手段！

// 增
// 1. 实现一个弹框打开关闭的交互效果
// 2. 实现的是一个表单 校验 单个校验 + 兜底校验[ref]

// 三个组件配合各有各的专门的作用
// el-form: 绑定表单对象 + 绑定规则对象
// el-form-item：prop的属性绑定规则
// el-input：双向绑定 v-model

// 3. 收集表单数据 确定提交接口
// 4. 提交成功之后的后续逻辑 提示用户 更新列表 重置数据 重置校验痕迹

// 下拉列表
// 1. 封装接口 获取数据  弹框打开 点击下拉框的同时获取接口
// 2. 使用下拉框组件渲染到对应的位置

import { getDepartments, addDepartments } from '@/api/departments'
import { getEmployeeSimple } from '@/api/employees'
import transTree from '@/utils/transTree'

export default {
  name: 'Department',
  data() {
    return {
      // 从哪里来？ 接口来 不受前端完全控制的  字段名可能不是label chilrdren
      // 因为这个问题  组件提供了一种修改默认识别字段的配置 defaultProps
      list: [],
      defaultProps: {
        label: 'name', // 告诉组件去识别 名称为 name的字段
        children: 'children'
      },
      dialogVisible: false,
      form: {
        name: '',
        code: '',
        manager: '',
        introduce: ''
      },
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: ['blur', 'change'] }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: ['blur', 'change'] }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: ['blur', 'change'] }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      },
      managerList: [],
      curId: null // 记录当前要给谁添加
    }
  },
  mounted() {
    this.fetchDepartmentList()
  },
  methods: {
    // 获取列表
    async fetchDepartmentList() {
      // 每一个await都应该使用try catch包裹一下
      const res = await getDepartments()
      this.list = transTree(res.data.depts)
      // depts：平铺的普通的数组 不是树形结构
      // 如何解决？
      // 1. 后端帮我处理一下 我要的不是这种 要的树形
      // 2. 前端进行格式化  平铺的数据 -> tree结构  交给组件
      //    查一下用现成的 -> 自己手写呢
    },
    addDepart(id) {
      this.curId = id
      this.dialogVisible = true
    },
    closeDialog() {
      console.log('弹框关闭嘞')
      this.dialogVisible = false
    },
    async openDialog() {
      // 调用接口
      const res = await getEmployeeSimple()
      console.log(res)
      this.managerList = res.data
    },
    confirm() {
      this.$refs.addForm.validate(async(valid) => {
        if (valid) {
          // 登录操作
          await addDepartments({
            ...this.form,
            pid: this.curId // 这里要的是 你给谁添加子部门就把它的id放过来
          })
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped></style>
